#include "if_utilits_c.h"
#include "debug_printf.h"
#include <ctype.h> // toupper
#include <stdlib.h> // atoi
#ifdef _WIN32
#include <winsock2.h>
#include <stdio.h>   
#include <string.h> 
#include <windef.h>   
#include <iphlpapi.h>  
#include <errno.h>
#pragma comment(lib,"iphlpapi.lib")
#else
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#endif

//************************************
// 归一化MAC地址字符串转大写并去除分隔符
// @param    const char * input    [in]  MAC地址字符串,为NULL忽略
// @param    char       * output   [out] 输出缓冲区,为NULL则原地转换
// @param    size_t       outputsz 输出缓冲区长度
// @return   int 成功返回true,否则返回false
//************************************
static bool normalize_nic(const char* input, char* output, size_t outputsz)
{	
	if (input)
	{
		int i = 0;
		int j = 0;
		while (input[i])
		{
			char c = input[i];
			char n;
			bool found = false;	
			if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
			{
				n = c;
				found = true;
			}
			else if (c >= 'a' && c <= 'f')
			{
				n = toupper(c);
				found = true;
			}
			if (found)/** 跳过非HEX字符 */
			{
				if (output)
				{
					if (j >= outputsz - 1 )
					{
						COM_PRINTF_DEBUG("ERROR:Insufficient output size %dz,%d writed", outputsz, j);
						return false;
					}
					output[j] = n;
				}
				else
				{
					((char*)input)[j] = n;
				}
				j++;
			}
			++i;
		}
		if (output)
		{
			/** 结尾0 */
			output[j] = '\0';
			return 12 == strlen(output);
		}
		else
		{
			((char*)input)[j] = '\0';
			return 12 == strlen((char*)input);
		}		
	}
	return true;
}
//************************************
// 将输入的.分割十进制的标准IP地址字符串(如'192.168.0.1')转为4字节数组,
// 如果输入格式不为.分隔的4节字符,返回空字符串
// @param    const    char * ipstr  .分割十进制的标准IP地址
// @param    unsigned char * ip4buf [out] 输出缓冲区长度要求为4
// @return   bool 解析成功返回true,否则返回false
//************************************
static bool parse_ip4(const char* ipstr, unsigned char *ip4buf)
{
	if(ipstr && ip4buf)
	{ 
		const char* endptr = ipstr + strlen(ipstr);
		const char* last = ipstr;
		const char* ptr = strchr(last, '.');
		int i = 0;
		while(last < endptr && ptr != NULL && ((ptr - last) > 0) && i < 4)
		{
			ip4buf[i++] = (unsigned char)atoi(ptr);
			last++;
			ptr = strchr(last, '.');
		}
		return i == 4;
	}
	return false;
}
//************************************
// 将二进制数据转为HEX字符串
// @param    const void * in       二进制数据
// @param    size_t       insz     二进制数据长
// @param    char       * hexbuf   [out]HEX字符串输出缓冲区
// @param    size_t       hexbufsz 输出缓冲区长度
// @return   int 成功返回0,否则返回-1
//************************************
static int bytes_to_hex(const void *in, size_t insz, char* hexbuf, size_t hexbufsz) {
	//const static char hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
	const static char hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'D', 'F' };
	if (in && hexbuf && insz && hexbufsz && hexbufsz>=((insz << 1) +1))
	{
		unsigned char *bytes = (unsigned char*)in;
		int i = 0;
		for (; i < insz; ++i) {
			hexbuf[i << 1]       = hex_char[bytes[i] >> 4  ]; /* 高四位 */ 
			hexbuf[(i << 1) + 1] = hex_char[bytes[i] & 0x0f]; /* 低四位 */ 
		}
		hexbuf[i<<1] = '\0';
		return 0;
	}
	return -1;
}
#if __linux__
//************************************
// 获取网卡设备MAC/IP地址
// @param    const char * required_name  指定网卡名,未指定则获取第一个非loopback网卡
// @param    int          addrtype       请求的地址类型:0:MAC地址,1:IP地址
// @param    bool         fmt            返回的数据是否格式化为可见字符串,
//                                       为true时将MAC地址格式化为16进制MAC地址字符串,IP地址格式化为.分割的十进制IP地址
// @param    char       * addr           [out] 返回的MAC/IP地址输出缓冲区
// @param    size_t       addrsz         输出缓冲区长度
// @param    bool         debugLog       是否输出调试信息
// @return   bool                        调用成功返回true,否则返回false
//************************************
static bool get_if_address(const char *required_name, int addrtype, bool fmt, char *addr,size_t addrsz, bool debugLog)
{
	if (NULL == addr || 0 == addrsz)
	{
		return false;
	}

	bool sucess = false;
	int fd, nic;
	struct ifreq buf[8];
	struct ifconf ifc;
	bool nameMatchRequired = required_name && strlen(required_name) > 0;
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
	{
		ifc.ifc_len = sizeof(buf);
		ifc.ifc_buf = (caddr_t)buf;
		if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
		{
			nic = ifc.ifc_len / sizeof(struct ifreq);
			for (int i = 0; i < nic; ++i)
			{
				if (nameMatchRequired && strcmp(required_name, buf[i].ifr_name))
				{
					continue;
				}
				if (ioctl(fd, SIOCGIFFLAGS, (char *)&buf[i]) == 0) {

					if ((buf[i].ifr_flags & IFF_LOOPBACK)) { // don't count loopback
						continue;
					}
					
					switch (addrtype)
					{
					case 0: 
					{
						/************************************************************************/
						/* 获取 MAC地址,如果不要求返回HEX字符串,则直接输出6字符二进制地址       */
						/* (输出缓冲区长度要求大于等于6)                                        */
						/* 否则转为16进制字符串输出(输出缓冲区长度要求大于12)                   */
						/************************************************************************/
						if (!(ioctl(fd, SIOCGIFHWADDR, (char *)&buf[i])))
						{
							if (!fmt) 
							{
								if (addrsz < 6) 
								{
									COM_PRINTF_DEBUG_IF(debugLog,"INSUFFICIENT addr length,6 required");
								}
								else
								{
									memcpy(addr, buf[i].ifr_hwaddr.sa_data, 6);
									sucess = true;
								}
							}
							else {
								if (addrsz < 13)
								{
									COM_PRINTF_DEBUG_IF(debugLog, "INSUFFICIENT addr length,13 required");
								}
								else
								{
									bytes_to_hex(buf[i].ifr_hwaddr.sa_data, 6, addr, addrsz);
									sucess = true;
								}
							}
							COM_PRINTF_DEBUG_IF(debugLog && sucess, "found network interface %s MAC: %s", buf[i].ifr_name, addr);
						}
						break;
					}
					case 1:
					default: 
					{
						/************************************************************************/
						/* 获取 IP 地址,如果要求返回.分割的十进制数字字符串,则直接输出          */
						/* sockaddr_in.sin_addr 字段(输出缓冲区长度要求大于等于16)              */
						/* 否则转为4字节二进制数据输出(输出缓冲区长度要求大于等于4)             */
						/************************************************************************/
						if (!(ioctl(fd, SIOCGIFADDR, (char *)&buf[i])))
						{
							/** 将地址转为.分割的十进制数字字符串 */
							char * ipstr = inet_ntoa(((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr);
							if (fmt)
							{
								size_t ipstrlen = strlen(ipstr);
								if (addrsz <= ipstrlen)
								{
									COM_PRINTF_DEBUG_IF(debugLog, "INSUFFICIENT addr length,%dz required", ipstrlen + 1);
								}
								else
								{
									strncpy(addr, ipstr, ipstrlen);
									sucess = true;
								}
							}
							else {
								if (addrsz < 4)
								{
									COM_PRINTF_DEBUG_IF(debugLog, "INSUFFICIENT addr length,4 required");
								}
								else
								{
									parse_ip4(ipstr, addr);
									sucess = true;
								}
							}
							COM_PRINTF_DEBUG_IF(debugLog && sucess, "found network interface %s IP: %s", buf[i].ifr_name, addr);
						}
						break;
					}
					}
				}
			}
			COM_PRINTF_DEBUG_IF(nameMatchRequired && debugLog && !sucess, "Not found adapter named: %s", required_name);
		}
		close(fd);
	}
	return sucess;
}
//************************************
// 获取网卡设备MAC地址
// @param    char       *        macbuf [out] MAC输出缓冲区,返回16进制MAC地址字符串
// @param    size_t            macbufsz MAC输出缓冲区长度
// @param    const char * required_name 指定网卡名,未指定(为NULL或空)则获取第一个非loopback网卡
// @param    bool                   fmt 返回的数据是否格式化为可见字符串,为true时将IP地址格式化为.分割的十进制IP地址
// @param    bool              debugLog 是否输出调试信息
// @return   bool                       调用成功返回true,否则返回false
//************************************
static bool get_mac(char * macbuf, size_t macbufsz,const char *required_name, bool fmt, bool debugLog)
{
	return get_if_address(required_name, 0, fmt, macbuf, macbufsz, debugLog);
}
//************************************
// 获取网卡设备IP地址
// @param    char       *        ipaddr [out] IP地址输出缓冲区,返回.分割十进制IP地址字符串
// @param    size_t            ipaddrsz 输出缓冲区长度
// @param    const char * required_name 指定网卡名,未指定(为NULL或空)则获取第一个非loopback网卡
// @param    bool                   fmt 返回的数据是否格式化为可见字符串,为true时将IP地址格式化为.分割的十进制IP地址
// @param    bool              debugLog 是否输出调试信息
// @return   bool                       调用成功返回true,否则返回false
//************************************
static bool get_ipaddr(char* ipaddr, size_t ipaddrsz,const char *required_name, bool fmt, bool debugLog)
{
	return get_if_address(required_name, 1, fmt,ipaddr, ipaddrsz, debugLog);
}
//************************************
// 执行command指定的控制台命令,返回结果保存在output,返回执行命令的状态码
// @param    const char *  command 要执行的命令字符串
// @param    bool d       debugLog 是否输出调试信息
// @param    char       *   output [out]命令输出缓冲区
// @param    size_t       outputsz 输出缓冲区长度
// @return   int 命令执行成功返回 0 ,失败则返回错误代码
//************************************
static int shell_command(const char* command, bool debugLog, char *output, size_t outputsz)
{
	if (NULL == command || 0 == strlen(command))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "command is NULL OR empty");
		return -1;
	}
	if (NULL == output || 0 == outputsz)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "output is NULL OR empty");
		return -1;
	}
	FILE   *stream;
	COM_PRINTF_DEBUG_IF(debugLog, "command [%s]", command);
	stream = popen(command, "r");
	if (!stream)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "fail to open pipe");
		return -1;
	}
	/** 将FILE* stream的数据流读取到buf中 */
	size_t readsize = fread(output, sizeof(char), outputsz, stream); 
	if (readsize >= outputsz)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "Insufficient output size");
		return -1;
	}
	/** 确保以0结尾 */
	output[readsize] = '\0';
	int code = pclose(stream);
	COM_PRINTF_DEBUG_IF(debugLog, "[%s] exitcode=%d", output, code);
	return code;
}
//************************************
// 通过执行shell命令("cat /sys/class/net/$ifname/address")获取MAC地址
// @param    const char  *     ifname 网卡名
// @param    bool            debugLog 是否输出调试信息
// @param          char  *        mac [out]输出缓冲区,返回16进制MAC地址字符串
// @param    bool               macsz 输出缓冲区长度
// @return   bool                     调用成功返回true,否则返回false
//************************************
static bool get_mac_by_cat_sys_class_net(const char* ifname, bool debugLog, char *mac, size_t macsz)
{
	if (NULL == ifname || 0 == strlen(ifname))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "ifname is NULL OR empty");
		return false;
	}
	if (NULL == mac || 0 == macsz)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "mac is NULL OR empty");
		return false;
	}
	char cmdbuf[256];
	char cmd[256] = { 0 };
	size_t wsz = snprintf(cmd, sizeof(cmd), "cat /sys/class/net/%s/address 2>/dev/null",ifname);
	if (wsz < 0 || wsz >= sizeof(cmd))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "Insufficient cmdbuf size,caused by too long ifname,snprintf return wsz=%dz",wsz);
		return false;
	}
	if (shell_command(cmd, debugLog, cmdbuf,sizeof(cmdbuf)))
	{
		return false;
	}
	*mac = '\0';
	if (normalize_nic(cmdbuf, mac, macsz))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "found network interface [%s] mac:[%s]", ifname, mac);
		return true;
	}
	COM_PRINTF_DEBUG_IF(debugLog, "normalize_nic fail: input: [%s] output: [%s]", cmdbuf,mac);
	return false;
}
//************************************
// 通过执行shell命令获取MAC地址
// @param     const char * required_name 指定网卡设备名称,未指定则获取第一个非loopback网卡
// @param     bool              debugLog 是否输出调试信息
// @param     char       *           mac [out]输出缓冲区,返回16进制MAC地址字符串
// @param     size_t               macsz 输出缓冲区长度
// @return    bool                       调用成功返回true,否则返回false
//************************************
static bool get_mac_by_pipe(const char* required_name, bool debugLog, char *mac, size_t macsz)
{
	char output[512];
	if (required_name && strlen(required_name))
	{
		return get_mac_by_cat_sys_class_net(required_name, debugLog, mac, macsz);
	}
	bool found = get_mac_by_cat_sys_class_net("eth0", debugLog, mac, macsz);
	if (found) {
		return true;
	}
	found = get_mac_by_cat_sys_class_net("wlan0", debugLog, mac, macsz);
	if (found) {
		return true;
	}
	/* 列出所有网卡设备名 */
	if (shell_command("ls /sys/class/net 2>/dev/null", debugLog, output, sizeof(output)))
	{
		return false;
	}
	if (strlen(output))
	{
		size_t outputlen = strlen(output);
		const char*sep = " \t\r\n";
		char*ptr = output;
		const char*last = output;
		do 
		{
			ptr = strpbrk(ptr, sep); // find separator
			if (ptr)
			{
				*ptr = '\0';
				/* 排除 lo 的所有网卡设备名称 */
				if (strcmp(last, "lo"))
				{
					// first ifname
					return get_mac_by_cat_sys_class_net(last, debugLog, mac, macsz);
				}
				if (ptr < (output + outputlen - 1))
				{
					last = ptr;
					ptr++;
					ptr += strspn(ptr, sep);// skip separator
				}
				else
				{
					break;
				}
			}
			else
			{
				// only one name
				return get_mac_by_cat_sys_class_net(output, debugLog, mac, macsz);
			}
		} while (ptr && * ptr);
	}
	COM_PRINTF_DEBUG_IF(debugLog, "not found network interface");
	return false;
}

#endif

bool ifu_get_ip_address(const char* ifname, char *ipbuf, size_t ipbufsz, bool debugLog)
{
	if (!(ipbuf && ipbufsz))
	{
		return false;
	}
	COM_PRINTF_DEBUG_IF(debugLog, "ifname [%s]", ifname  ? ifname : "null");

 #ifdef _WIN32
	ULONG bufsize = 0;
	if (ERROR_BUFFER_OVERFLOW != GetAdaptersInfo(NULL, &bufsize))
	{
		COM_PRINTF_DEBUG_IF(debugLog,"GetAdaptersInfo Failed! ErrorCode: %d", GetLastError());
		return false;
	}
	IP_ADAPTER_INFO* adapterInfo = (IP_ADAPTER_INFO*)malloc(bufsize);
	if (NULL == adapterInfo)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "MEM ERROR");
		return false;
	}
	bool sucess = false;
	ULONG status = GetAdaptersInfo(adapterInfo, &bufsize);
	
	if (ERROR_SUCCESS == status)
	{
		if (NULL == ifname || 0 == strlen(ifname))
		{
			char* szip = (char*)adapterInfo[0].IpAddressList.IpAddress.String;
			size_t sziplen = strlen(szip);
			if (sziplen >= ipbufsz)
			{
				COM_PRINTF_DEBUG_IF(debugLog, "TO SMALL ipbuf, %dz required", sziplen);
			}
			else
			{
				strcpy(ipbuf, szip);
				COM_PRINTF_DEBUG_IF(debugLog, "found network interface %s IP:%s", adapterInfo[0].AdapterName, ipbuf);
				sucess = true;
			}
		}
		else
		{
			/** 遍历所有网卡,查找指定名字的网卡并返回 */ 
			PIP_ADAPTER_INFO pAdapterInfo = &adapterInfo[0];
			while (pAdapterInfo)
			{
				COM_PRINTF_DEBUG_IF(debugLog, "---- network interface %s", pAdapterInfo->AdapterName);
				if (0 == strncmp(pAdapterInfo->AdapterName, ifname, strlen(ifname)))
				{
					char* szip = (char*)pAdapterInfo->IpAddressList.IpAddress.String;
					size_t sziplen = strlen(szip);
					if (sziplen >= ipbufsz)
					{
						COM_PRINTF_DEBUG_IF(debugLog, "TO SMALL ipbuf, %dz required", sziplen);
						break;
					}
					strcpy(ipbuf, szip);
					COM_PRINTF_DEBUG_IF(debugLog, "found network interface %s IP:%s", pAdapterInfo->AdapterName, ipbuf);
					sucess = true;
					break;
				}
				pAdapterInfo = pAdapterInfo->Next;
			}
			COM_PRINTF_DEBUG_IF(debugLog && !sucess, "Not found adapter named: %s", ifname);
		}
	}
	else 
	{
		COM_PRINTF_DEBUG_IF(debugLog,"GetAdaptersInfo Failed! ErrorCode: %s", GetLastError());
	}
	free(adapterInfo);
	return sucess;
#elif __linux__
	/************************************************************************/
	/* ifname 为空或NULL时优先查找etho,wlan0                                */
	/************************************************************************/
	if (ifname && strlen(ifname))
	{
		return get_ipaddr(ipbuf, ipbufsz, ifname, true, debugLog);
	}
	if (get_ipaddr(ipbuf, ipbufsz,"eth0", true, debugLog))
	{
		return true;
	}
	if (get_ipaddr(ipbuf, ipbufsz,"wlan0", true, debugLog))
	{
		return true;
	}
	return get_ipaddr(ipbuf, ipbufsz, ifname, true, debugLog);
#else
	SAMPLE_LOG_IF(debugLog, "UNIMPLEMENTED");
	return false;
#endif
}
bool ifu_get_mac_address(const char* ifname, char *macbuf,size_t macbufsz, bool debugLog)
{
	if (!(macbuf && macbufsz && macbufsz > 12))
	{
		return false;
	}
	COM_PRINTF_DEBUG_IF(debugLog, "ifname [%s]", ifname ? ifname : "null");
#ifdef _WIN32
	ULONG bufsize = 0;
	if (ERROR_BUFFER_OVERFLOW != GetAdaptersInfo(NULL, &bufsize))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "GetAdaptersInfo Failed! ErrorCode: %s", GetLastError());
		return false;
	}

	IP_ADAPTER_INFO* adapterInfo = (IP_ADAPTER_INFO*)malloc(bufsize);
	if (NULL == adapterInfo)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "MEM ERROR");
		return false;
	}
	bool sucess = false;
	ULONG status = GetAdaptersInfo(adapterInfo, &bufsize);

	if (ERROR_SUCCESS == status)
	{
		if (NULL == ifname || 0 == strlen(ifname))
		{
			bytes_to_hex(adapterInfo[0].Address, 6, macbuf, macbufsz);
			//snprintf(macbuf, macbufsz,"%0X%0X%0X%0X%0X%0X",
			//	adapterInfo[0].Address[0], adapterInfo[0].Address[1], adapterInfo[0].Address[2], 
			//	adapterInfo[0].Address[3], adapterInfo[0].Address[4], adapterInfo[0].Address[5]);
			COM_PRINTF_DEBUG_IF(debugLog, "found network interface %s MAC:%s ", adapterInfo[0].AdapterName, macbuf);
			return true;
		}
		else
		{
			/* 遍历所有网卡,查找指定名字的网卡并返回 */ 
			PIP_ADAPTER_INFO pAdapterInfo = &adapterInfo[0];
			while (pAdapterInfo)
			{
				COM_PRINTF_DEBUG_IF(debugLog, "---- network interface %s", pAdapterInfo->AdapterName);
				if (0 == strncmp(pAdapterInfo->AdapterName, ifname, strlen(ifname)))
				{
					bytes_to_hex(pAdapterInfo->Address, 6, macbuf, macbufsz);
					COM_PRINTF_DEBUG_IF(debugLog, "found network interface %s MAC:%s", pAdapterInfo->AdapterName, macbuf);
					sucess = true;
					break;
				}
				pAdapterInfo = pAdapterInfo->Next;
			}
			COM_PRINTF_DEBUG_IF(debugLog && ! sucess, "Not found adapter named: %s", ifname);
		}
	}
	else 
	{
		COM_PRINTF_DEBUG_IF(debugLog, "GetAdaptersInfo Failed! ErrorCode: %s", GetLastError());
	}
	free(adapterInfo);
	return sucess;
#else
	/************************************************************************/
	/* 优先使用shell命令获取MAC地址                                         */
	/************************************************************************/
	if (get_mac_by_pipe(ifname, debugLog, macbuf, macbufsz))
	{
		return true;
	}
	/************************************************************************/
	/* ifname 为空或NULL时优先查找etho,wlan0                                */
	/************************************************************************/
	if (ifname && strlen(ifname))
	{
		return get_mac(macbuf, macbufsz,ifname, true, debugLog);
	}
	if (get_mac(macbuf, macbufsz,"eth0", true,debugLog))
	{
		return true;
	}
	if (get_mac(macbuf, macbufsz,"wlan0", true,debugLog))
	{
		return true;
	}
	return get_mac(macbuf, macbufsz,ifname, true, debugLog);
#endif
}

#define CHECK_NICBUF \
if (wsz < 0 || wsz >= remainsz) { \
	COM_PRINTF_DEBUG_IF(debugLog, "TO SMALL foundnics"); \
} else {\
	wpos += wsz; remainsz -= wsz; \
}


bool ifu_find_nic_by_mac(const char* input_mac, char * ifname, size_t ifsz, char  * foundnics, size_t nicbufsz, bool debugLog)
{
	if ( NULL == input_mac || 0 == strlen(input_mac))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "input_mac is NULL OR empty");
		return false;
	}
	if (NULL == ifname && 0 == ifsz)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "ifname is NULL OR empty");
		return false;
	}
	char mac_address[13];
	if (!normalize_nic(input_mac, mac_address,sizeof(mac_address)))
	{
		return false;
	}
	COM_PRINTF_DEBUG_IF(debugLog, "mac_address [%s]", mac_address);
	ifname[0] = '\0';
	foundnics[0] = '\0';
	size_t wpos = 0;
	size_t remainsz = nicbufsz;
#ifdef _WIN32
	ULONG bufsize = 0;
	if (ERROR_BUFFER_OVERFLOW != GetAdaptersInfo(NULL, &bufsize))
	{
		COM_PRINTF_DEBUG_IF(debugLog, "GetAdaptersInfo Failed! ErrorCode: %s", GetLastError());
		return false;
	}

	IP_ADAPTER_INFO* adapterInfo = (IP_ADAPTER_INFO*)malloc(bufsize);
	if (NULL == adapterInfo)
	{
		COM_PRINTF_DEBUG_IF(debugLog, "MEM ERROR");
		return false;
	}
	bool sucess = false;
	ULONG status = GetAdaptersInfo(adapterInfo, &bufsize);
	int cnt = 0;
	if (ERROR_SUCCESS == status)
	{
		// 遍历所有网卡,查找指定MAC地址的网卡并返回
		PIP_ADAPTER_INFO pAdapterInfo = &adapterInfo[0];
		
		while (pAdapterInfo)
		{
			char macbuf[13];
			bytes_to_hex(adapterInfo[0].Address, 6, macbuf, sizeof(macbuf));

			COM_PRINTF_DEBUG_IF(debugLog, "found network interface %s %s", pAdapterInfo->AdapterName, macbuf);
			if (0 == strncmp(macbuf,mac_address,sizeof(macbuf)))
			{
				size_t namelen = strlen(pAdapterInfo->AdapterName);
				if (namelen >= ifsz)
				{
					COM_PRINTF_DEBUG_IF(debugLog, "TO SMALL ifbufsz,%dz required", namelen);
					break;
				}
				strncpy(ifname,pAdapterInfo->AdapterName, ifsz);
			}

			/************************************************************************/
			/* 如果foundnics不为空则输出找到所有网卡设备信息                        */
			/************************************************************************/
			if (foundnics && nicbufsz)
			{
				int wsz;
				if (cnt > 0)
				{
					wsz = snprintf(foundnics + wpos, remainsz, ",");
					/** 检查是否溢出 */
					CHECK_NICBUF
				}
				wsz = snprintf(foundnics + wpos, remainsz, "%s/%s", pAdapterInfo->AdapterName, macbuf);
				/** 检查是否溢出 */
				CHECK_NICBUF				
			}
			pAdapterInfo = pAdapterInfo->Next;
			cnt++;
		}	
		COM_PRINTF_DEBUG_IF(debugLog && 0 == strlen(ifname), "Not found adapter mac: %s,found nic:%s", mac_address,foundnics);
		sucess = strlen(ifname) > 0;
	}
	else
	{
		COM_PRINTF_DEBUG_IF(debugLog, "GetAdaptersInfo Failed! ErrorCode: %s", GetLastError());
	}
	free(adapterInfo);
	if (foundnics && nicbufsz)
	{
		foundnics[nicbufsz - 1] = '\0';
	}
	return sucess;
#else

	bool sucess = false;
	int fd, nic;
	struct ifreq buf[8];
	struct ifconf ifc;
	int cnt = 0;
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
	{
		ifc.ifc_len = sizeof(buf);
		ifc.ifc_buf = (caddr_t)buf;
		if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
		{
			nic = ifc.ifc_len / sizeof(struct ifreq);
			for (int i = 0; i < nic; ++i)
			{
				if (ioctl(fd, SIOCGIFFLAGS, (char *)&buf[i]) == 0) {

					if ((buf[i].ifr_flags & IFF_LOOPBACK)) { // don't count loopback
						continue;
					}

					if (!(ioctl(fd, SIOCGIFHWADDR, (char *)&buf[i])))
					{
						char macbuf[13];
						bytes_to_hex(buf[i].ifr_hwaddr.sa_data, 6, macbuf, sizeof(macbuf));
						COM_PRINTF_DEBUG_IF(debugLog && sucess, "found network interface %s MAC: %s", buf[i].ifr_name, macbuf);
						if (0 == strncmp(macbuf, mac_address, sizeof(macbuf)))
						{
							size_t namelen = strlen(buf[i].ifr_name);
							if (namelen >= ifsz)
							{
								COM_PRINTF_DEBUG_IF(debugLog, "TO SMALL ifbufsz,%dz required", namelen);
								break;
							}
							strncpy(ifname, buf[i].ifr_name, ifsz);
						}
						/************************************************************************/
						/* 如果foundnics不为空则输出找到所有网卡设备信息                        */
						/************************************************************************/
						if (foundnics && nicbufsz)
						{
							int wsz;
							if (cnt > 0)
							{
								wsz = snprintf(foundnics + wpos, remainsz, ",");
								/** 检查是否溢出 */
								CHECK_NICBUF
							}
							wsz = snprintf(foundnics + wpos, remainsz, "%s/%s", buf[i].ifr_name, macbuf);
							/** 检查是否溢出 */
							CHECK_NICBUF
						}
						cnt++;
					}
				}
			}
			COM_PRINTF_DEBUG_IF(debugLog && 0 == strlen(ifname), "Not found adapter mac: %s,found nic:%s", mac_address, foundnics);
			sucess = strlen(ifname) > 0;
		}
		close(fd);
	}
	if (foundnics && nicbufsz)
	{
		foundnics[nicbufsz - 1] = '\0';
	}
	return sucess;
#endif
}

bool ifu_check_mac_matched(const char* mac, bool debugFlag, char *errmsg,size_t errbufsz)
{
	char ifname[128];
	char foundnics[512];
	/* 检查指定MAC地址是否为本机的MAC地址 */
	if (!ifu_find_nic_by_mac(mac, ifname,sizeof(ifname), foundnics,sizeof(foundnics), debugFlag))
	{
		com_debug_snprintf(errmsg,errbufsz,"device MAC %s mismatch with current device,found nics:%", mac, foundnics);
		COM_PRINTF_DEBUG_IF(debugFlag,"error %s", errmsg);
		return false;
	}
	COM_PRINTF_DEBUG_IF(debugFlag,"net interface device with mac %s named %s", mac, ifname);
	return true;
}
